using System.Threading;
using System.Threading.Tasks;
using EasyNetQ;
using MalwareMultiScan.Api.Services.Interfaces;
using MalwareMultiScan.Backends.Messages;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.Logging;

namespace MalwareMultiScan.Api.Services.Implementations
{
    /// <inheritdoc />
    public class ReceiverHostedService : IReceiverHostedService
    {
        private readonly IBus _bus;
        private readonly IConfiguration _configuration;
        private readonly ILogger<ReceiverHostedService> _logger;
        private readonly IScanResultService _scanResultService;

        /// <summary>
        /// Initialize receiver hosted service.
        /// </summary>
        /// <param name="bus">EasyNetQ bus.</param>
        /// <param name="configuration">Configuration.</param>
        /// <param name="scanResultService">Scan result service.</param>
        /// <param name="logger">Logger.</param>
        public ReceiverHostedService(IBus bus, IConfiguration configuration, IScanResultService scanResultService,
            ILogger<ReceiverHostedService> logger)
        {
            _bus = bus;
            _configuration = configuration;
            _scanResultService = scanResultService;
            _logger = logger;
        }


        /// <inheritdoc />
        public Task StartAsync(CancellationToken cancellationToken)
        {
            _bus.Receive<ScanResultMessage>(_configuration.GetValue<string>("ResultsSubscriptionId"), async message =>
            {
                message.Threats ??= new string[] { };

                _logger.LogInformation(
                    $"Received a result from {message.Backend} for {message.Id} " +
                    $"with threats {string.Join(",", message.Threats)}");

                await _scanResultService.UpdateScanResultForBackend(
                    message.Id, message.Backend, message.Duration, true,
                    message.Succeeded, message.Threats);
            });

            _logger.LogInformation(
                "Started hosted service for receiving scan results");

            return Task.CompletedTask;
        }

        /// <inheritdoc />
        public Task StopAsync(CancellationToken cancellationToken)
        {
            _bus?.Dispose();

            _logger.LogInformation(
                "Stopped hosted service for receiving scan results");

            return Task.CompletedTask;
        }
    }
}